/*
AcessOS 0.1
Kernel Main
*/
#include <system.h>
#include <build.h>
#include <proc.h>
#include <proc_int.h>
#include <mboot.h>
#include <config.h>

// ==== EXTERNAL FUNCTIONS ====
extern void fat_install();
extern void Ext2_Install();
extern void FDD1_Load();
extern void Config_ExecuteScript();
extern void Module_InstallStatics();
extern int	ProcDev_Install();

// ==== GLOBALS ====
Uint32	giAcessVersion = 0x101;	//AcessOS v1

/**
 \fn void kmain(Uint32 mbMagic, mboot_info *mboot)
 \brief C section of kernel entrypoint
 \param mbMagic	Contents of eax at the start of the kernel
 \param mboot	Pointer to multiboot information structure
 
 This is the core C function in Acess and is the "parent"
 of the entire operating system.
*/
void kmain(Uint32 mbMagic, mboot_info *mboot)
{
	 int	pid;
	char	*argv[] = {"init", NULL};
	char	*envp[] = {"ACESS_VERSION=AcessOS 1.0", "PATH=/Acess", NULL};

	// Initialise Machine State
	GDT_Install();
	IDT_Install();
	isrs_install();
	irq_install();
	
	// Start Text Logging
	VGAText_Install();
	
	// Print Acess Header
	LogF("====================================================================\n");
	LogF("--------------------------  Acess OS v0.5  -------------------------\n");
	LogF("====================================================================\n");
	
	// Install Timer
	time_install();
	// Install Keyboard
	Keyboard_Install();
	// Install Memory Manager
	memmanager_install((mboot->mem_upper + (0x100000>>10)) << 10);		//Supply Memory in Bytes
	// Initialise Heap
	Heap_Init();
	
	if(mbMagic == MULTIBOOT_MAGIC)
	{
		// Load Configuration from MBoot Structure
		Config_LoadMBoot(mboot);
	}
	else
	{
		// Loads Configuration from Defaults
		Config_LoadDefaults();
	}
	// Print out Configuration
	Config_PrintConfig();
	
	// Multitasking
	Proc_Install();
	Syscall_Install();
	VM8086_Install();
	
	
	// Install VFS and FileSystems
	vfs_install();
		fat_install();
		Ext2_Install();
	
	// Install Drivers
	ProcDev_Install();
	setup_disks();	// IDE PIO Driver - Not thread safe
	tty_install();	// Terminal
	PCI_Install();	// PCI Bus
	Module_InstallStatics();	// Statically Linked Drivers
	FDD1_Load();	// Load FDD Driver
	
	// Mount Floppy
	vfs_mknod("/Mount/fd0", VFS_FFLAG_DIRECTORY);
	VFS_MountName("/Devices/fdd/0", "/Mount/fd0", "", "fat");
	
	// Execute Sysconfig Script
	Config_ExecuteScript();
	
	LogF("=== Loading User Mode Shell.\n");
	pid = Proc_KFork();	// Use KFork to reduce overhead
	if(pid == 0) {
		Proc_Execve(gsInitProgram, argv, envp, 3);
		panic("Unable to start shell/init\n");
		return;
	}
	
	if(pid < 0)
		panic("Unable to Fork Kernel!\n");
	
	//LogF("--- User Shell Running. (PID #%i)\n", pid);
	
	//Proc_WaitPid(pid, 0);	// Wait for shell to complete
	
	//LogF("=== Shell Exited\n");
	for (;;)	Proc_Sleep();	// Yeild Until Message
}
